查看原文
其他

北邮人论坛爬虫实操:session替代cookies

2017-12-01

作者 大邓

一、北邮人论坛

BBS式微的今天,北邮人论坛这个比水木清华差不多年纪的BBS。不但没有out,社区依旧很活跃。及时华丽上线移动版,依旧保持着生机,是国内高校排名前三的高校BBS,实在是难得。

应朋友需要,提高给我了北邮人的账号密码,让我爬帖子名和帖子内回复。

https://bbs.byr.cn

二、特殊的北邮人论坛

按照往常的套路,按F12打开开发者工具,选择Network。


填写好账号、密码,点击登陆,观察开发者工具中请求及响应结果。我们经过检查,发现ajax_login.json这个包有点特殊,代表着登陆成功与否。

于是大邓似乎懂了,写好代码伪装成浏览器发起了对北邮人论坛的第一轮“冲锋“请求。

2.1 不用cookie,我们用session

之前的爬虫基本上都是headers和cookies两个参数就解决了爬虫,绕过了模拟登陆这关。

但是cookies是有有效期,过了有效期代码就无法运行。因为这次要交付代码给这位朋友后续使用,懒人大邓今天不得不又查阅了requests库高级用法,第一次尝试使用会话session。

打个不太恰当的比方。cookie的作用类似于进北邮校门前,大邓要掏出兜里的学生证,说我是北邮xx学生,请放行。而session呢,我直接刷脸进北邮,不用再繁琐的掏腰包拿学生证。

headers = {'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'}

byr_data = {'id': user, 'passwd': password}

#创建会话session
session = requests.Session()

login_url = 'https://bbs.byr.cn/user/ajax_login.json'

#使用session会话对北邮人发起请求
req = session.post(login_url, data=byr_data, headers=my_header)    
# 查看登录是否成功
print(req.json())

2.2 万事开头难


都说万事开头难,爬虫的开头就是抓包及模拟登陆。

大邓在这里卡住了,中途又使用用selenium试图解决这个地方。确实selenium比较好解决这个问题,但是速度太慢了。于是又回来继续使用requests发起请求,研究到底是哪里出的问题。

2.3 问题出在headers

后来我将请求头中的所有选项依次一个个的试验,最终发现都是报错。只有下面的这个headers选项加到headers后,对北邮人论坛发请求得到期望的正确登陆数据。

my_headers = {'x-requested-with': 'XMLHttpRequest'}

2.4 模拟登陆成功

之后将代码中的headers换成

my_headers = {'x-requested-with': 'XMLHttpRequest'}

代码运行结果如下图,显示成功登陆了!!!


完整代码

我爬取的版块是 北邮人论坛>信息社会>考研专版


但经过发现,只要改红色圈住的链接部分就可以对不同的版块抓信息。

难点都在前面解说了,直接附上项目代码。

from pyquery import PyQuery as pq
import requests
import time
import csv
import re

def article(pp,x_doc,session,my_header,writer,user):    """    对每个帖子进行数据获取    :param pp: 版块的第几页    :param x_doc: html的pyquery对象    :param session: 会话对象    :param my_header: 请求头    :param writer: csv文件的指针    :param user: 北邮人用户名    """    for tr in x_doc('tbody').children():        link = 'https://bbs.byr.cn'+pq(tr).find('.title_9 a').attr('href')+'?_uid={usr}'.format(usr=user)+'&p={p}'        
       title = pq(tr).find('.title_9 a').text()        
       com_num = int(pq(tr).find('.title_11.middle').text())        #计算该帖子有多少页回复        article_pages = int(com_num/10)+1            #翻页,获取每页的所有评论        for p in range(1,article_pages+1):            a_resp = session.get(link.format(p=p), headers=my_header)            a_doc = pq(a_resp.text)            com_texts = ''            for com in a_doc.items('.a-content-wrap'):                comment = str(com.children().eq(3)).replace('<br/>', '') 
               #用正则剔除无效信息(只保留中文,。!?@等符号)                comment = ''.join([x for x in re.findall(r'[\u4e00-\u9fa5A-Z0-9a-z\,,。!!@?\? \t\r]*', comment) if 'bd' not in x])                if comment:                    com_texts+=comment+'\r'                print(pp,title,comment)            #写入csv文件            try:                writer.writerow((title,com_texts))            except:                pass


def get_data(user, password, board,filename):    """    获取北邮人论坛考研版块的数据,保存到csv中    :param user: 北邮人论坛账号    :param password: 北邮人论坛密码    :param board: 北邮人论坛子版块    :param filename: 数据保存的文件名    """        #创建csv文件    csvf = open('{}.csv'.format(filename),'a+',encoding='gbk',newline='')    writer = csv.writer(csvf)    writer.writerow(('帖子名','回复'))        #登录北邮人论坛,创建session会话    my_header = {'x-requested-with': 'XMLHttpRequest'}    byr_data = {'id': user, 'passwd': password}    session = requests.Session()    r_url = 'https://bbs.byr.cn/user/ajax_login.json'    req = session.post(r_url, data=byr_data, headers=my_header)
   # 查看登录是否成功    print(req.json())

   #开始在考研版块翻页,获取每页中的帖子信息    first_page_url = 'https://bbs.byr.cn/board/{board}?p={page}&_uid={usr}'.format(board=board,page=1, usr=user)    first_resp = session.get(first_page_url, headers=my_header)    first_html = first_resp.text    first_doc = pq(first_html)    pages = int(first_doc('.page-main').children().eq(-2).find('a').text())    for page in range(1, pages + 1):        if page == 1:            #对该版块的第一页的所有帖子进行抓取            article(page,first_doc, session, my_header, writer, user)        else:            x_page_url = 'https://bbs.byr.cn/board/{board}?p={page}&_uid={usr}'.format(board=board,page=page, usr=user)            x_resp = session.get(x_page_url, headers=my_header)            x_doc = pq(x_resp.text)            #对该版块剩余页面的所有帖子进行抓取            article(page,x_doc, session, my_header, writer, user)    csvf.close()        

user='xxxxxxx'
password='********'
board = 'AimGraduate' #信息社会>考研专版
filename = 'data'
get_data(user,password,board,filename)


教程及代码下载

链接: https://pan.baidu.com/s/1kVb1P7x 密码: m3dn

觉得有收获可以送支鹅毛信哦~(^_^)


历史文章:

数据采集

selenium驱动器配置详解

爬虫神器PyQuery的使用方法

pyquery爬取豆瓣读书

pyquery一些自定义的用法

【视频】猫途鹰网站评论数据抓取

【视频讲解】在scrapy框架中如何使用selenium?

【实战视频】使用scrapy写爬虫-爬知乎live

简易SQLite3数据库学习

【视频教程】对视频进行基本操作

【视频】抓包小练习-B站评论数据抓取

fake-useragent库:值得花2分钟学习的库

【视频】爬取饿了么平台上的门店信息

如何抓取视频资源-以头条视频为例

当爬虫遭遇验证码,怎么办

【视频】手把手教你抓美女~

【视频】有了selenium,小白也可以自豪的说:“去TMD的抓包、cookie”

【视频】快来get新技能--抓包+cookie,爬微博不再是梦

【视频教程】用python批量抓取简书用户信息

用Python抓取百度地图里的店名,地址和联系方式

文本处理分析

gensim:用Word2Vec进行文本分析

RAKE:快速自动抽取关键词算法

对于中文,nltk能做哪些事情

用nltk计算词语间的点互信息值PMI

用SenticNet库做细粒度情感分析

如何对csv文件中的文本数据进行分析处理

复杂网络分析数据准备篇

文本分析之网络关系

用词云图解读“于欢案”

基于共现发现人物关系的python实现

用pyecharts制作词云图

图片数据处理

OpenCV:快速入门图片人脸识别

好玩的OpenCV:图片操作的基本知识(1)

好玩的OpenCV:图像操作的基本知识(2)

OpenCV:计算图片有多色

如何对数据进行各种排序?

其他

迅雷不给力,我DIY了个下载器

【视频】初学者必看:python环境配置

开扒皮自己微信的秘密

初识装饰器函数

计算运行时间-装饰器实现

花十分钟,给爱机安装个MongoDB

chardet库:轻松识别文件的编码格式

使用Python登录QQ邮箱发送QQ邮件

WTF Python: 开启你的懵逼模式

8行代码实现微信聊天机器人

使用Python+OpenCV进行面部合成

十分钟学会用Flask发邮件


十分钟入门常用的json库


优雅简洁的列表推导式

【资源帖】简单易懂的机器学习视频教程


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存